import React, { PureComponent } from 'react'
import { DndProvider } from 'react-dnd'
import { HTML5Backend } from 'react-dnd-html5-backend'
import { history } from '@umijs/max'
import {
  Button, Dropdown, Form, Input, Menu, message, Modal, Popconfirm, Tabs,
} from 'antd'
import { DownOutlined, ExclamationCircleFilled } from '@ant-design/icons'
import { getHashParameterByName } from '@/utils/helper'
import styles from './index.less'
import {
  BreadcrumbBar, HufuTreeTitle, ProTable, ProTableOptions, ProTree, searchTreeListByName,
} from '@/components'
import Configuration from './Configuration'
import QualityCreate from './QualityCreate'
import {
  addParExpression, deleteParExpression, deleteRule, getParExpressions, tryrun,
} from './api'

const menus = [{ name: '数据质量' }, { name: '监控规则', href: '/dataQuality/ruleConfig' }, { name: '配置监控规则' }]
const { Item } = Form
const TabPane = Tabs.TabPane

const rowSelection = {
  type: 'checkbox',
}

export default class RuleConfigSee extends PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      tblId: getHashParameterByName('tblId'),
      tableName: getHashParameterByName('tableName'),
      hasPartition: getHashParameterByName('hasPartition'),
      columns: [
        {
          title: '规则名称',
          dataIndex: 'ruleName',
          key: 'ruleName',
          width: '8%',
        },
        {
          title: '规则字段',
          dataIndex: 'fieldNames',
          key: 'fieldNames',
          width: '8%',
          render: (text, record) => (!text || text === '' ? '--' : text),
        },
        {
          title: '规则模板',
          dataIndex: 'templateName',
          key: 'templateName',
          width: '8%',
        },
        {
          title: '强/弱',
          dataIndex: 'ruleStrength',
          key: 'ruleStrength',
          width: '7%',
          render: (text) => <span>{text ? '弱' : '强'}</span>,
        },
        {
          title: '比较方式',
          dataIndex: 'compareType',
          key: 'compareType',
          width: '10%',
          render: (text) => <span>{text}</span>,
        },
        {
          title: '期望值',
          dataIndex: 'expectValue',
          key: 'expectValue',
          width: '7%',
        },
        {
          title: '创建人',
          dataIndex: 'createUsername',
          key: 'createUsername',
          width: '8%',
        },
        {
          title: '创建时间',
          dataIndex: 'createTime',
          key: 'createTime',
          width: '10%',
        },
        {
          title: '修改时间',
          dataIndex: 'updateTime',
          key: 'updateTime',
          width: '10%',
        },
        {
          title: '修改人',
          dataIndex: 'updateUsername',
          key: 'updateUsername',
          width: '8%',
        },
        {
          title: '操作',
          dataIndex: 'operation',
          key: 'operation',
          width: '16%',
          render: (text, record, index) => (
            <ProTableOptions>
              <span onClick={() => {
                const { activeKey } = this.state
                this.setState({
                  id: record.id,
                  isQualityCreate: true,
                  ruleDiy2: activeKey,
                })
              }}
              >编辑
              </span>
              <Popconfirm title="确定要删除吗？" onConfirm={() => { this.deleteRule(record.id) }} okText="是" cancelText="否">
                <span>
                  删除
                </span>
              </Popconfirm>
            </ProTableOptions>
          ),
        },
      ],
      columns2: [
        {
          title: '规则名称',
          dataIndex: 'ruleName',
          key: 'ruleName',
          width: '10%',
        },
        {
          title: '强/弱',
          dataIndex: 'ruleStrength',
          key: 'ruleStrength',
          width: '7%',
          render: (text) => <span>{text ? '弱' : '强'}</span>,
        },
        {
          title: '比较方式',
          dataIndex: 'compareType',
          key: 'compareType',
          width: '8%',
          render: (text) => <span>{text}</span>,
        },
        {
          title: '期望值',
          dataIndex: 'expectValue',
          key: 'expectValue',
          width: '10%',
        },
        {
          title: '创建人',
          dataIndex: 'createUsername',
          key: 'createUsername',
          width: '7%',
        },
        {
          title: '创建时间',
          dataIndex: 'createTime',
          key: 'createTime',
          width: '15%',
        },
        {
          title: '修改时间',
          dataIndex: 'updateTime',
          key: 'updateTime',
          width: '15%',
        },
        {
          title: '修改人',
          dataIndex: 'updateUsername',
          key: 'updateUsername',
          width: '8%',
        },
        {
          title: '操作',
          dataIndex: 'operation',
          key: 'operation',
          width: '16%',
          render: (text, record, index) => (
            <ProTableOptions>
              <span onClick={() => {
                const { activeKey } = this.state
                this.setState({
                  id: record.id,
                  isQualityCreate: true,
                  ruleDiy2: activeKey,
                })
              }}
              >编辑
              </span>
              <Popconfirm title="确定要删除吗？" onConfirm={() => { this.deleteRule(record.id) }} okText="是" cancelText="否">
                <span>
                  删除
                </span>
              </Popconfirm>
            </ProTableOptions>
          ),
        },
      ],
      loading: false,
      treeData: [],
      treeDataNew: [],
      ruleIds: [],
      selectedKeys: [],
      activeKey: '0',
      query: {
        ruleDiy: '0',
        tblId: getHashParameterByName('tblId'),
      },
      tabs: [{
        title: '模板规则',
        key: '0',
      }, {
        title: '自定义规则',
        key: '1',
      }],
    }
    this.fileForm = React.createRef()
    this.configurationDom = React.createRef()
    this.qualityCreate = React.createRef()
  }

  componentDidMount() {
    this.getParExpressions()
  }

  deleteRule = (id) => {
    const { activeKey, selectedKeys, tblId } = this.state
    deleteRule({ id }).then((res) => {
      if (res.status === 200) {
        this.setState({
          query: {
            ruleDiy: activeKey,
            parExpressionId: selectedKeys[0] || '',
            tblId,
          },
        })
        message.success(res.msg)
      } else {
        message.error(res.msg)
      }
    })
  }

  getParExpressions = () => {
    const {
      tblId, tableName, hasPartition, activeKey,
    } = this.state
    getParExpressions({
      tblId,
      tableName,
      hasPartition,
    }).then((res) => {
      const treeData = []
      const treeDataNew = []
      res.data && res.data.map((obj) => {
        treeData.push({
          id: obj.id,
          title: obj.partitionExpress,
          key: obj.id,
        })
        treeDataNew.push({
          id: obj.id,
          title: obj.partitionExpress,
          key: obj.id,
        })
      })
      this.setState({
        treeData,
        treeDataNew,
        selectedKeys: treeData[0] ? [treeData[0].id] : [],
        partitionExpression: treeData[0] ? treeData[0].title : null,
        query: {
          parExpressionId: treeData[0] ? treeData[0].id : '',
          ruleDiy: activeKey,
          tblId,
        },
      })
    })
  }

  renderTreeNodes = (data) => {
    const tempArr = []
    const { hasPartition } = this.state
    data.map((item) => {
      const {
        title, children, ...restProps
      } = item
      const tempObj = {
        icon: <span className={styles.icon_fenqu}><i className="iconfont icon-fenqu" /></span>,
        ...restProps,
      }
      tempObj.title = (
        <HufuTreeTitle
          title={title}
          key={item.id}
          item={item.title}
          icon
          operations={hasPartition == 1 ? [
            <span
              key={1}
              onClick={() => this.showModal(item)}
            >
              编辑
            </span>,
            <span
              key={2}
              onClick={() => {
                Modal.confirm({
                  title: '确认要删除这个分区表达式吗？',
                  icon: <ExclamationCircleFilled />,
                  content: '删除后数据将无法恢复，请谨慎操作',
                  okText: '删除',
                  cancelText: '取消',
                  okButtonProps: {
                    danger: true,
                  },
                  onOk: () => {
                    this.deleteParExpression(item)
                  },
                })
              }}
            >
              删除
            </span>,
          ] : null}
        />
      )
      if (item.children) {
        tempObj.children = this.renderTreeNodes(item.children)
      }
      tempArr.push(tempObj)
    })
    return tempArr
  }

  deleteParExpression = (item) => {
    deleteParExpression({
      id: item.id,
    }).then((res) => {
      if (res.status === 200) {
        this.getParExpressions()
        message.success(res.msg)
      } else {
        message.error(res.msg)
      }
    })
  }

  onSelect = (selectedKeys, e) => {
    const { activeKey, tblId } = this.state
    this.setState({
      selectedKeys,
      partitionExpression: e.node.title.props.item,
      query: {
        parExpressionId: selectedKeys[0] || '',
        ruleDiy: activeKey,
        tblId,
      },
    })
  }

  tabsChangeTask = (activeKey) => {
    const { selectedKeys, tblId } = this.state
    this.setState({
      activeKey,
      query: {
        ruleDiy: activeKey,
        parExpressionId: selectedKeys[0] || '',
        tblId,
      },
    })
  }

  addParExpression = () => {
    const { tblId, tableName, id } = this.state
    this.fileForm.current.validateFields().then(values => {
      addParExpression({
        ...values,
        tableName,
        tblId,
        id: id || null,
      }).then((res) => {
        if (res.status === 200) {
          this.setState({
            isShowFiles: false,
          })
          this.getParExpressions()
          message.success(res.msg)
        } else {
          message.error(res.msg)
        }
      })
    })
  }

  showModal = (item) => {
    this.setState({
      id: item.id,
      isShowFiles: true,
    }, () => {
      this.fileForm.current.setFieldsValue({
        parExpression: item.title,
      })
    })
  }

  tryrun = () => {
    const { tblId, selectedKeys, ruleIds } = this.state
    tryrun({
      partitionId: selectedKeys[0],
      tblId,
      ruleIds: ruleIds ? ruleIds.join(',') : null,
    }).then((res) => {
      if (res.status === 200) {
        message.success(res.msg)
      } else {
        message.error(res.msg)
      }
    })
  }

  render() {
    const {
      treeData, treeDataNew, selectedKeys, loading, hasPartition, activeKey, query, tabs, id, tblId,
    } = this.state
    const menu = (
      <Menu
        onClick={(data) => {
          this.setState({
            ruleDiy2: data.key,
            isQualityCreate: true,
            id: null,
          })
        }}
      >
        <Menu.Item key={0} name="模板规则">
          模板规则
        </Menu.Item>
        <Menu.Item key={1} name="自定义规则">
          自定义规则
        </Menu.Item>
      </Menu>
    )
    return (
      <div className={`${styles.page_content_with_breadcrumb} ${styles.theme_design}`}>
        <BreadcrumbBar menu={menus} />
        <div className={styles.back_bar}>
          <i className="iconfont icon-zuo" />
          <span onClick={() => {
            history.push('/dataQuality/ruleConfig')
          }}
          >配置监控规则
          </span>
          <Dropdown
            trigger={['click']}
            overlay={menu}
          >
            <Button disabled={treeDataNew && treeDataNew.length} type="primary">创建规则 <DownOutlined /></Button>
          </Dropdown>
          <Button
            disabled={!(this.state.dataTable && this.state.dataTable.length)}
            onClick={() => {
              this.setState({
                isConfiguration: true,
              })
            }}
          >设置调度
          </Button>
          <Button disabled={!(this.state.dataTable && this.state.dataTable.length)} onClick={this.tryrun}>试跑
          </Button>
        </div>
        <div className={styles.page_content}>
          <div className={styles.page_content_left}>
            <ProTree
              showLine
              showSearch
              // showTitle={hasPartition == 1}
              // title={' '}
              operations={hasPartition == 1 ? [
                <i
                  key="1"
                  className="iconfont icon-tianjia"
                  title="新建分区"
                  onClick={() => {
                    this.setState({
                      isShowFiles: true,
                      id: null,
                    })
                  }}
                />,
              ] : null}
              treeData={treeDataNew}
              renderTreeNodes={this.renderTreeNodes}
              selectedKeys={selectedKeys}
              onSelect={this.onSelect}
              ref={(dev) => (this.tree = dev)}
              search={(name) => {
                const searchTree = searchTreeListByName(
                  name,
                  treeData,
                  'title',
                )
                const treeDataNews = searchTree.result
                this.setState(
                  {
                    treeDataNew: treeDataNews,
                  },
                  () => {
                    this.tree.onExpand(searchTree.fatchIds)
                  },
                )
              }}
            />
          </div>
          <div className={styles.page_content_right}>
            <Tabs
              type="editable-card"
              onChange={this.tabsChangeTask}
              activeKey={activeKey}
              hideAdd
              style={{ marginTop: '.24rem' }}
              className={`${styles.page_content_tabs} ${styles.editor_box_tabs}`}
            >
              {tabs && tabs.map((item) => (
                <TabPane
                  style={{ width: '100%', height: '100%', marginTop: '.16rem' }}
                  tab={item.title}
                  key={item.key}
                  closable={false}
                >
                  <DndProvider backend={HTML5Backend}>
                    <ProTable
                      url="/api/v1/dataQuality/manager/rules"
                      query={query}
                      columns={item.key === '0' ? this.state.columns : this.state.columns2}
                      loading={loading}
                      rowKey="id" // key传递的是否有效，影响rowSelection的使用
                      getTableDataFinished={(data) => {
                        this.setState({
                          dataTable: data,
                        })
                      }}
                      rowSelection={rowSelection}
                      getSelectedRowKeys={(selectedRowKeys) => {
                        this.setState({
                          ruleIds: selectedRowKeys,
                        })
                      }}
                    />
                  </DndProvider>
                </TabPane>
              ))}
            </Tabs>
          </div>
        </div>
        <Modal
          title={id ? '编辑分区表达式' : '添加分区表达式'}
          visible={this.state.isShowFiles}
          confirmLoading={this.state.navListSpinning}
          cancelText="取消"
          okText="保存"
          onOk={this.addParExpression}
          onCancel={() => {
            this.setState({
              isShowFiles: false,
            })
          }}
          maskClosable={false}
        >
          <div className={styles.file_box}>
            <Form
              ref={this.fileForm}
              labelCol={{ span: 5 }}
              wrapperCol={{ span: 19 }}
              autoComplete="off"
            >
              <Item
                label="分区表达式"
                name="parExpression"
                rules={[
                  { required: true, message: '请输入分区表达式' },
                ]}
              >
                <Input placeholder="请输入分区表达式" />
              </Item>
            </Form>
          </div>
        </Modal>
        <Modal
          destroyOnClose
          width={720}
          title="设置调度"
          visible={this.state.isConfiguration}
          confirmLoading={this.state.navListSpinning}
          cancelText="取消"
          okText="保存"
          onOk={() => {
            this.configurationDom.current.saveSchedule()
          }}
          onCancel={() => {
            this.setState({
              isConfiguration: false,
            })
          }}
          maskClosable={false}
        >
          <div className={styles.file_box}>
            <Configuration
              ref={this.configurationDom}
              show={(bool) => {
                if (bool) {
                  this.setState({
                    navListSpinning: false,
                  })
                } else {
                  this.setState({
                    isConfiguration: false,
                    navListSpinning: false,
                  })
                }
              }}
              showIs={() => {
                this.setState({
                  navListSpinning: true,
                })
              }}
            />
          </div>
        </Modal>
        <Modal
          destroyOnClose
          title={this.state.ruleDiy2 == 0 ? '模板规则' : '自定义规则'}
          visible={this.state.isQualityCreate}
          confirmLoading={this.state.navListSpinning}
          cancelText="取消"
          okText="保存"
          onOk={() => {
            this.qualityCreate.current.onFinish()
          }}
          onCancel={() => {
            this.setState({
              isQualityCreate: false,
            })
          }}
          maskClosable={false}
        >
          <div className={styles.file_box}>
            <QualityCreate
              ref={this.qualityCreate}
              partitionExpression={this.state.partitionExpression}
              partitionId={selectedKeys[0]}
              ruleDiy={this.state.ruleDiy2}
              id={id}
              show={() => {
                this.setState({
                  isQualityCreate: false,
                  query: {
                    parExpressionId: selectedKeys[0] || '',
                    ruleDiy: activeKey,
                    tblId,
                  },
                })
              }}
            />
          </div>
        </Modal>
      </div>
    )
  }
}
